package ua.amsoft.brelok.dao;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Date;

import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

import ua.amsoft.brelok.db.DatabaseOpenHelper;
import ua.amsoft.brelok.dto.DepartamentUsageResultReports;
import ua.amsoft.brelok.manager.DatabaseManager;
import ua.amsoft.brelok.util.DateTimeUtils;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.util.Log;

/**
 * @author Tair Mustafaiev
 */
public class DepartamentUsageReportsDAO implements IDepartamentUsageReportsDAO {
    
    private static final String TAG = DepartamentUsageReportsDAO.class.getName();
    
    private static final String SELECT_BY_UPDATED_DATE = "select * from "
            + DatabaseOpenHelper.DUR_TABLE_NAME + " where "
            + DatabaseOpenHelper.DUR_DATE_UPDATED_COLUMN + "=?";
    
    private static final String SELECT_ALL = "select * from " + DatabaseOpenHelper.DUR_TABLE_NAME;
    
    private final DatabaseManager databaseManager;
    
    /**
     * Constructor
     * 
     * @param context - {@link Context}
     */
    public DepartamentUsageReportsDAO(final Context context) {
        this.databaseManager = new DatabaseManager(context);
    }
    
    @Override
    public DepartamentUsageResultReports get() {
        try {
            this.databaseManager.open();
            final String query = DepartamentUsageReportsDAO.SELECT_ALL;
            final Cursor result = this.databaseManager.select(query, null);
            return parseCursor(result);
        } catch (final Exception e) {
            Log.e(DepartamentUsageReportsDAO.TAG, e.getLocalizedMessage());
        } finally {
            this.databaseManager.close();
        }
        return null;
    }
    
    @Override
    public DepartamentUsageResultReports getByUpdatedDate(final Date date) {
        try {
            this.databaseManager.open();
            final String[] selectionArgs = new String[] { DateTimeUtils.formatInputDate(date) };
            final Cursor result = this.databaseManager.select(
                    DepartamentUsageReportsDAO.SELECT_BY_UPDATED_DATE, selectionArgs);
            return parseCursor(result);
        } catch (final Exception e) {
            Log.e(DepartamentUsageReportsDAO.TAG, e.getLocalizedMessage());
        } finally {
            this.databaseManager.close();
        }
        return null;
    }
    
    @Override
    public void insert(final ContentValues values) {
        try {
            this.databaseManager.open();
            this.databaseManager.insert(DatabaseOpenHelper.DUR_TABLE_NAME, null, values);
        } finally {
            this.databaseManager.close();
        }
    }
    
    @Override
    public void deleteAll() {
        try {
            this.databaseManager.open();
            this.databaseManager.delete(DatabaseOpenHelper.DUR_TABLE_NAME, null, null);
        } finally {
            this.databaseManager.close();
        }
    }
    
    @Override
    public void update(final ContentValues values, final String whereClause,
            final String[] whereArgs) {
        try {
            this.databaseManager.open();
            this.databaseManager.executeUpdate(DatabaseOpenHelper.DUR_TABLE_NAME, values,
                    whereClause, whereArgs);
        } finally {
            this.databaseManager.close();
        }
    }
    
    @Override
    public void forceUpdateTable(final ContentValues values) {
        try {
            this.databaseManager.open();
            this.databaseManager.delete(DatabaseOpenHelper.DUR_TABLE_NAME, null, null);
            this.databaseManager.insert(DatabaseOpenHelper.DUR_TABLE_NAME, null, values);
        } finally {
            this.databaseManager.close();
        }
    }
    
    /**
     * Parses {@link Cursor} object returned from DB and reads XML file's byte
     * array to {@link DepartamentUsageResultReports} object
     * 
     * @param cursor - an {@link Cursor} object
     * @return {@link DepartamentUsageResultReports} object parsed from XML
     * @throws Exception - throwed exception
     */
    private DepartamentUsageResultReports parseCursor(final Cursor cursor) throws Exception {
        if (cursor.moveToFirst()) {
            byte[] file = null;
            String dateUpdated = "";
            while (!cursor.isAfterLast()) {
                file = cursor.getBlob(cursor.getColumnIndex(DatabaseOpenHelper.DUR_FILE_COLUMN));
                dateUpdated = cursor.getString(cursor
                        .getColumnIndex(DatabaseOpenHelper.DUR_DATE_UPDATED_COLUMN));
                cursor.moveToNext();
            }
            final Serializer serial = new Persister();
            final InputStream inputStream = new ByteArrayInputStream(file);
            final DepartamentUsageResultReports reports = serial.read(
                    DepartamentUsageResultReports.class, inputStream);
            reports.setUpdateDate(DateTimeUtils.parseOutputDate(dateUpdated));
            return reports;
        }
        return null;
    }
    
}
